﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace BostonAzureSiteWebRole.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //ViewData["Message"] = "Welcome to the web home of the Boston Azure User Group";

            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        public ActionResult Contact()
        {
            return View();
        }

        public ActionResult SubscribeResult()
        {
            return View();
        }

        public ActionResult SignUp(string emailAddress)
        {
            // Constant Contact doc: http://developer.constantcontact.com/doc/manageContacts#create_contact
            // Authentication doc:   http://developer.constantcontact.com/doc/authenticationBasic

            if (isEmail(emailAddress))
            {

                // Create LoginCreditials
                CredentialCache LoginCredentials = new CredentialCache();

                // Add a new credential for this account
                LoginCredentials.Add(new Uri("http://api.constantcontact.com/ws/customers/bostonazure"),
                    // Set up URI for API site
                    "Basic", // Basic login type
                    new NetworkCredential(ConfigurationManager.AppSettings["ConstantContactUser"], // Set up API Username (APIKey%Username)
                        ConfigurationManager.AppSettings["ConstantContactPass"])); // Password 

                // Create WebRequest
                var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.constantcontact.com/ws/customers/bostonazure/contacts");

                // URI for the POST 
                // Set Request to be a POST
                httpWebRequest.Method = "POST";

                // Set the ContentType property.
                httpWebRequest.ContentType = "application/atom+xml";

                // Set Request credentials
                httpWebRequest.Credentials = LoginCredentials;

                var str = new StringBuilder();
                str.Append("<entry xmlns='http://www.w3.org/2005/Atom'>");
                str.Append("<title type='text'></title>"); // not used by CC, okay if empty, but required by Atom standard
                str.Append("<updated>2008-07-23T14:21:06.407Z</updated>"); // not used by CC, but required to be a date by Atom standard
                str.Append("<author></author>"); // not used by CC, okay if empty, but required by Atom standard
                //str.Append("<id>data:,none</id>"); // not used by CC, required to be a URI by Atom standard
                str.Append("<id>http://bostonazure.org/2011/atompub</id>"); // not used by CC, required to be a URI by Atom standard
                str.Append("<summary type='text'>Contact</summary>");
                str.Append("<content type='application/vnd.ctct+xml'>");
                str.Append("<Contact xmlns='http://ws.constantcontact.com/ns/1.0/' id='http://api.constantcontact.com/ws/customers/bostonazure/contacts'>");
                str.Append("<EmailAddress>" + emailAddress + "</EmailAddress>");
                str.Append("<FirstName></FirstName>"); // TODO: how to capture user's real First Name? (ConstantContact)
                str.Append("<LastName></LastName>"); // TODO: how to capture user's real Last Name? (ConstantContact)
                str.Append("<OptInSource>ACTION_BY_CONTACT</OptInSource>");
                str.Append("<ContactLists>");
                str.Append("<ContactList id='http://api.constantcontact.com/ws/customers/bostonazure/lists/3'/>");
                str.Append("</ContactLists>");
                str.Append("</Contact>");
                str.Append("</content>");
                str.Append("</entry>");

                // Set up the XML Document, application dependant 

                // Convert XMLData to byteArray for posting
                byte[] byteArray = Encoding.UTF8.GetBytes(str.ToString());

                // Send POST request
                // Recast the response to HttpWebResponse for easier processing
                // Place in a try block to ensure that any errors are caught
                try
                {
                    // Set the ContentLength portion of the header
                    httpWebRequest.ContentLength = byteArray.Length; string XMLResponse = "Bytes to send:" + byteArray.Length;

                    // Create a stream for the POST Request
                    // Note: Remember to add using System.IO
                    Stream streamRequest = httpWebRequest.GetRequestStream();

                    // Write the data to the stream.
                    streamRequest.Write(byteArray, 0, byteArray.Length);
                    streamRequest.Close();
                    using (var httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse())
                    {
                        // Process the response as needed
                        // This is a generic StreamReader to read the entire response in
                        // You can recast this as any type of stream derivative
                        var reader = new StreamReader(httpWebResponse.GetResponseStream());

                        // Read the entire XML response to a string
                        // Note there may not be a XML response for a successful POST
                        XMLResponse += httpWebResponse.StatusCode + httpWebResponse.StatusDescription + reader.ReadToEnd();

                        // Close Reader
                        reader.Close();

                        // Close the response to free up the system resources
                        httpWebResponse.Close();

                        ViewData["SubmitStatus"] = 0;
                        ViewData["SubmitResponse"] = httpWebResponse.StatusCode + httpWebResponse.StatusDescription;
                    }
                }
                catch (WebException e)
                {
                    // Get the web exception type and response code
                    ViewData["SubmitStatus"] = e.Message.IndexOf("409") >= 0 ? 409 : 500;
                    ViewData["SubmitResponse"] = "WebException:" + e.Status + " With response:" + e.Message;
                }

                catch (Exception e)
                {
                    // Get the exception type
                    ViewData["SubmitStatus"] = 500;
                    ViewData["SubmitResponse"] = "Exception:" + e.Message;
                }
            }
            else
            {
                // Get the exception type
                ViewData["SubmitStatus"] = -1;
                ViewData["SubmitResponse"] = "Invalid format.";
            }

            return View("SubscribeResult");
        }


        public bool isEmail(string inputEmail)
        {
            if (String.IsNullOrEmpty(inputEmail))
            {
                return false;
            }

            // TODO: this needs some unit tests, e.g., these should all be allowed:
            // foo@example.com
            // foo+bar@example.com
            // foo+bar+1@example.com
            // foo@sub.domain.example.com
            // foo@invalid.us
            // foo@example.com.uk

            const string expression = @"^([a-zA-Z0-9_\-\.\+]+)@((\[[0-9]{1,3}" +
                                      @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                                      @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";

            var regex = new Regex(expression);
            return regex.IsMatch(inputEmail);
        }
    }
}
